package com.sayp.netdisk.service;

import com.sayp.netdisk.controller.FileController;
import com.sayp.netdisk.dao.*;
import com.sayp.netdisk.pojo.Code;
import com.sayp.netdisk.util.FileUtil;
import com.sayp.netdisk.util.LogUtil;
import com.sayp.netdisk.util.PropertyUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;

import java.io.File;
import java.util.ArrayList;
import java.util.List;

@Service
@Transactional
public class DeleteService {
    @Autowired
    private FileDao fileDao;
    @Autowired
    private ShareService shareService;
    @Autowired
    private CodeDao codeDao;
    @Autowired
    private UserService userService;
    @Autowired
    private org.springframework.beans.factory.BeanFactory factory;
    @Autowired
    private FileUtil fileUtil;
    @Autowired
    private PropertyUtil propertyUtil;
    @Autowired
    private LogUtil logUtil;
    private final Logger logger = LoggerFactory.getLogger(FileController.class);


    /**
     * 删除文件
     * @param fids
     * @return
     */
    public boolean delFile(int[] fids,int uid){
        List<File> files = new ArrayList<>();
        for (int fid : fids) {
            java.io.File f = new java.io.File(propertyUtil.getUserDir(),fileDao.findByFid(fid).getPath());
            files.add(f);

            if(!this.delSingleFile(fid,uid)){
                TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                return false;
            }

            //检查是否完全删除了激活码
            List<Code> codes = codeDao.findByFid(fid);
            if(codes!=null && codes.size()!=0){
                for (Code c : codes) {
                    if(!codeDao.del(c.getCid()))return false;
                }
            }

            if(fileDao.findByFid(fid)!=null && !fileDao.del(fid)){
                TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();//删除不成功则事务回滚
                return false;
            }
        }
        //增加用户剩余容量
        if(!userService.changeUserRemain(uid,0,this.getFileRemain(files))){
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return false;
        }

        if(!fileUtil.delFile(files)){
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return false;
        }
        return true;
    }

    private boolean delSingleFile(int fid,int uid){
        if(!shareService.cancelShare(fid))return false;//删除文件对应激活码
        com.sayp.netdisk.pojo.File file = fileDao.findByFid(fid);
        if(file.getIsDir()==0)return fileDao.del(fid);
        List<com.sayp.netdisk.pojo.File> sons = fileDao.findByParentId(fid,uid);//根据父文件查询子文件
        if(sons==null || sons.size()==0)
            return fileDao.del(fid);
        for (com.sayp.netdisk.pojo.File son : sons) {
            if(!this.delSingleFile(son.getFid(),uid))
                return false;
            if(son.getIsDir()==1){
                if(fileDao.findByFid(son.getFid())!=null && !fileDao.del(son.getFid()))return false;
            }
        }
        //输出日志
        logUtil.outPutLog("unknown","删除了文件",file.getFName(),logger,0);
        return true;
    }


    /**
     * 获取文件总大小(B)
     * @param files  要统计的文件
     * @return
     */
    public double getFileRemain(List<java.io.File> files){
        if(files==null || files.size()==0)return 0;
        double a = 0;
        for (java.io.File f : files) {
            a+=this.getFileRemain(f);
        }
        return a;
    }

    private double getFileRemain(java.io.File file){
        if(!file.exists())return 0;
        if(!file.isDirectory())return file.length();
        java.io.File[] files = file.listFiles();
        if(files==null || files.length==0)return file.length();
        int a = 0;
        for (java.io.File f : files) {
            a+=this.getFileRemain(f);
        }
        return file.length()+a;
    }
}
